using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

namespace GameSystems
{
    /// <summary>
    /// 设备绑定系统 - 管理用户设备认证和绑定
    /// </summary>
    public class DeviceBindingSystem : MonoBehaviour
    {
        #region Data Classes

        /// <summary>
        /// 设备信息结构
        /// </summary>
        [Serializable]
        public class DeviceInfo
        {
            public string deviceId;
            public string deviceName;
            public string deviceType;
            public DateTime firstLogin;
            public DateTime lastLogin;
            public bool isTrusted;
            public string location;
            public string ipAddress;

            public DeviceInfo()
            {
                deviceId = SystemInfo.deviceUniqueIdentifier;
                deviceName = SystemInfo.deviceName;
                deviceType = GetDeviceType();
                firstLogin = DateTime.Now;
                lastLogin = DateTime.Now;
                isTrusted = false;
                location = "Unknown";
                ipAddress = "Unknown";
            }

            private static string GetDeviceType()
            {
                switch (Application.platform)
                {
                    case RuntimePlatform.Android:
                        return "Android";
                    case RuntimePlatform.IPhonePlayer:
                        return "iOS";
                    case RuntimePlatform.WindowsPlayer:
                    case RuntimePlatform.WindowsEditor:
                        return "Windows";
                    case RuntimePlatform.OSXPlayer:
                    case RuntimePlatform.OSXEditor:
                        return "macOS";
                    case RuntimePlatform.LinuxPlayer:
                    case RuntimePlatform.LinuxEditor:
                        return "Linux";
                    default:
                        return "Unknown";
                }
            }
        }

        #endregion

        #region Events

        /// <summary>
        /// 设备绑定成功事件
        /// </summary>
        [Serializable] public class DeviceBoundEvent : UnityEvent<string> { }

        /// <summary>
        /// 设备解绑事件
        /// </summary>
        [Serializable] public class DeviceUnboundEvent : UnityEvent<string> { }

        /// <summary>
        /// 新设备检测事件
        /// </summary>
        [Serializable] public class NewDeviceDetectedEvent : UnityEvent<DeviceInfo> { }

        /// <summary>
        /// 设备验证成功事件
        /// </summary>
        [Serializable] public class DeviceVerifiedEvent : UnityEvent<DeviceInfo> { }

        /// <summary>
        /// 设备验证失败事件
        /// </summary>
        [Serializable] public class DeviceVerificationFailedEvent : UnityEvent<string> { }

        #endregion

        #region Serialized Fields

        [Header("设备绑定配置")]
        [Tooltip("是否启用设备绑定")]
        [SerializeField] private bool enableDeviceBinding = false;

        [Tooltip("最大绑定设备数量")]
        [SerializeField] private int maxBoundDevices = 5;

        [Tooltip("新设备验证超时时间（秒）")]
        [SerializeField] private float verificationTimeout = 300f;

        [Tooltip("是否自动信任新设备")]
        [SerializeField] private bool autoTrustNewDevice = false;

        [Tooltip("是否启用地理位置验证")]
        [SerializeField] private bool enableLocationVerification = true;

        [Header("安全设置")]
        [Tooltip("是否启用设备指纹验证")]
        [SerializeField] private bool enableFingerprintVerification = true;

        [Tooltip("是否启用IP地址验证")]
        [SerializeField] private bool enableIPVerification = true;

        [Tooltip("可疑IP地址列表")]
        [SerializeField] private List<string> suspiciousIPList = new List<string>();

        [Header("调试选项")]
        [Tooltip("是否启用调试日志")]
        [SerializeField] private bool enableDebugLogs = true;

        [Tooltip("测试模式 - 跳过设备验证")]
        [SerializeField] private bool testMode = false;

        #endregion

        #region Events

        [Header("事件回调")]
        [Tooltip("设备绑定成功时触发")]
        public DeviceBoundEvent OnDeviceBound;

        [Tooltip("设备解绑时触发")]
        public DeviceUnboundEvent OnDeviceUnbound;

        [Tooltip("检测到新设备时触发")]
        public NewDeviceDetectedEvent OnNewDeviceDetected;

        [Tooltip("设备验证成功时触发")]
        public DeviceVerifiedEvent OnDeviceVerified;

        [Tooltip("设备验证失败时触发")]
        public DeviceVerificationFailedEvent OnDeviceVerificationFailed;

        #endregion

        #region Private Fields

        private Dictionary<string, DeviceInfo> boundDevices = new Dictionary<string, DeviceInfo>();
        private string currentUser;
        private DeviceInfo currentDevice;
        private bool isVerificationInProgress = false;
        private Coroutine verificationCoroutine;

        // 设备数据文件路径
        private const string DeviceDataKey = "DeviceBindingData";

        #endregion

        #region Unity Lifecycle

        /// <summary>
        /// 初始化组件
        /// </summary>
        private void Awake()
        {
            InitializeCurrentDevice();
            LoadDeviceData();
        }

        /// <summary>
        /// 清理资源
        /// </summary>
        private void OnDestroy()
        {
            SaveDeviceData();

            if (verificationCoroutine != null)
            {
                StopCoroutine(verificationCoroutine);
            }
        }

        /// <summary>
        /// 应用暂停时保存数据
        /// </summary>
        private void OnApplicationPause(bool pauseStatus)
        {
            if (pauseStatus)
            {
                SaveDeviceData();
            }
        }

        /// <summary>
        /// 应用退出时保存数据
        /// </summary>
        private void OnApplicationQuit()
        {
            SaveDeviceData();
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// 验证设备
        /// </summary>
        /// <param name="username">用户名</param>
        /// <returns>验证结果</returns>
        public bool VerifyDevice(string username)
        {
            if (!enableDeviceBinding || testMode)
            {
                LogDebug("设备绑定未启用或测试模式，跳过验证");
                return true;
            }

            currentUser = username;

            // 检查是否为已知设备
            if (IsKnownDevice())
            {
                UpdateLastLogin();
                OnDeviceVerified?.Invoke(currentDevice);
                return true;
            }

            // 检查是否超过最大绑定设备数量
            if (boundDevices.Count >= maxBoundDevices)
            {
                OnDeviceVerificationFailed?.Invoke("已达到最大设备绑定数量");
                return false;
            }

            // 新设备检测
            OnNewDeviceDetected?.Invoke(currentDevice);

            if (autoTrustNewDevice)
            {
                BindDevice();
                return true;
            }

            // 需要额外验证
            return StartDeviceVerification();
        }

        /// <summary>
        /// 绑定当前设备
        /// </summary>
        public void BindDevice()
        {
            if (currentDevice == null)
            {
                LogError("当前设备信息为空");
                return;
            }

            if (boundDevices.ContainsKey(currentDevice.deviceId))
            {
                LogWarning("设备已绑定");
                return;
            }

            // 收集设备信息
            CollectDeviceInfo();

            // 添加到绑定设备列表
            boundDevices[currentDevice.deviceId] = currentDevice;
            currentDevice.isTrusted = true;

            // 保存数据
            SaveDeviceData();

            LogDebug($"设备已绑定: {currentDevice.deviceName} ({currentDevice.deviceId})");
            OnDeviceBound?.Invoke(currentDevice.deviceId);
        }

        /// <summary>
        /// 解绑设备
        /// </summary>
        /// <param name="deviceId">设备ID</param>
        public void UnbindDevice(string deviceId)
        {
            if (!boundDevices.ContainsKey(deviceId))
            {
                LogWarning("设备未绑定");
                return;
            }

            boundDevices.Remove(deviceId);
            SaveDeviceData();

            LogDebug($"设备已解绑: {deviceId}");
            OnDeviceUnbound?.Invoke(deviceId);
        }

        /// <summary>
        /// 获取所有绑定设备
        /// </summary>
        /// <returns>绑定设备列表</returns>
        public List<DeviceInfo> GetBoundDevices()
        {
            return new List<DeviceInfo>(boundDevices.Values);
        }

        /// <summary>
        /// 检查设备是否受信任
        /// </summary>
        /// <param name="deviceId">设备ID</param>
        /// <returns>是否受信任</returns>
        public bool IsDeviceTrusted(string deviceId)
        {
            if (boundDevices.ContainsKey(deviceId))
            {
                return boundDevices[deviceId].isTrusted;
            }
            return false;
        }

        /// <summary>
        /// 清除所有绑定设备
        /// </summary>
        public void ClearAllBoundDevices()
        {
            boundDevices.Clear();
            SaveDeviceData();
            LogDebug("已清除所有绑定设备");
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// 初始化当前设备信息
        /// </summary>
        private void InitializeCurrentDevice()
        {
            currentDevice = new DeviceInfo();
            LogDebug($"当前设备: {currentDevice.deviceName} ({currentDevice.deviceType})");
        }

        /// <summary>
        /// 检查是否为已知设备
        /// </summary>
        private bool IsKnownDevice()
        {
            if (boundDevices.ContainsKey(currentDevice.deviceId))
            {
                currentDevice = boundDevices[currentDevice.deviceId];
                return true;
            }
            return false;
        }

        /// <summary>
        /// 更新最后登录时间
        /// </summary>
        private void UpdateLastLogin()
        {
            if (currentDevice != null)
            {
                currentDevice.lastLogin = DateTime.Now;
                SaveDeviceData();
            }
        }

        /// <summary>
        /// 启动设备验证流程
        /// </summary>
        private bool StartDeviceVerification()
        {
            if (isVerificationInProgress)
            {
                LogWarning("设备验证正在进行中");
                return false;
            }

            isVerificationInProgress = true;
            verificationCoroutine = StartCoroutine(DeviceVerificationCoroutine());
            return false;
        }

        /// <summary>
        /// 设备验证协程
        /// </summary>
        private IEnumerator DeviceVerificationCoroutine()
        {
            LogDebug("开始设备验证流程");

            // 收集设备信息
            CollectDeviceInfo();

            // 检查设备指纹
            if (enableFingerprintVerification && !VerifyDeviceFingerprint())
            {
                OnDeviceVerificationFailed?.Invoke("设备指纹验证失败");
                isVerificationInProgress = false;
                yield break;
            }

            // 检查IP地址
            if (enableIPVerification && !VerifyIPAddress())
            {
                OnDeviceVerificationFailed?.Invoke("IP地址验证失败");
                isVerificationInProgress = false;
                yield break;
            }

            // 模拟验证延迟
            yield return new WaitForSeconds(2f);

            // 验证成功
            isVerificationInProgress = false;
            OnDeviceVerified?.Invoke(currentDevice);
        }

        /// <summary>
        /// 收集设备信息
        /// </summary>
        private void CollectDeviceInfo()
        {
            if (currentDevice == null) return;

            // 获取IP地址（模拟）
            currentDevice.ipAddress = GetPublicIPAddress();

            // 获取地理位置（模拟）
            if (enableLocationVerification)
            {
                currentDevice.location = GetDeviceLocation();
            }
        }

        /// <summary>
        /// 验证设备指纹
        /// </summary>
        private bool VerifyDeviceFingerprint()
        {
            // 实际项目中，这里应该实现真正的设备指纹验证
            // 例如：硬件信息、系统配置、浏览器指纹等
            LogDebug("设备指纹验证通过");
            return true;
        }

        /// <summary>
        /// 验证IP地址
        /// </summary>
        private bool VerifyIPAddress()
        {
            string currentIP = GetPublicIPAddress();

            if (suspiciousIPList.Contains(currentIP))
            {
                LogWarning($"检测到可疑IP地址: {currentIP}");
                return false;
            }

            LogDebug($"IP地址验证通过: {currentIP}");
            return true;
        }

        /// <summary>
        /// 获取公网IP地址（模拟）
        /// </summary>
        private string GetPublicIPAddress()
        {
            // 实际项目中，这里应该调用IP查询API
            return "192.168.1.100";
        }

        /// <summary>
        /// 获取设备位置（模拟）
        /// </summary>
        private string GetDeviceLocation()
        {
            // 实际项目中，这里应该调用地理位置API
            return "Beijing, China";
        }

        /// <summary>
        /// 加载设备数据
        /// </summary>
        private void LoadDeviceData()
        {
            if (PlayerPrefs.HasKey(DeviceDataKey))
            {
                try
                {
                    string jsonData = PlayerPrefs.GetString(DeviceDataKey);
                    var deviceData = JsonUtility.FromJson<DeviceBindingData>(jsonData);

                    if (deviceData != null && deviceData.devices != null)
                    {
                        boundDevices.Clear();
                        foreach (var device in deviceData.devices)
                        {
                            boundDevices[device.deviceId] = device;
                        }
                        LogDebug($"已加载 {boundDevices.Count} 个绑定设备");
                    }
                }
                catch (Exception e)
                {
                    LogError($"加载设备数据失败: {e.Message}");
                }
            }
        }

        /// <summary>
        /// 保存设备数据
        /// </summary>
        private void SaveDeviceData()
        {
            try
            {
                var deviceData = new DeviceBindingData
                {
                    devices = new List<DeviceInfo>(boundDevices.Values),
                    lastUpdated = DateTime.Now
                };

                string jsonData = JsonUtility.ToJson(deviceData, true);
                PlayerPrefs.SetString(DeviceDataKey, jsonData);
                PlayerPrefs.Save();

                LogDebug($"已保存 {boundDevices.Count} 个绑定设备");
            }
            catch (Exception e)
            {
                LogError($"保存设备数据失败: {e.Message}");
            }
        }

        #endregion

        #region Debug Methods

        /// <summary>
        /// 调试日志
        /// </summary>
        private void LogDebug(string message)
        {
            if (enableDebugLogs)
                Debug.Log($"[DeviceBindingSystem] {message}");
        }

        /// <summary>
        /// 警告日志
        /// </summary>
        private void LogWarning(string message)
        {
            if (enableDebugLogs)
                Debug.LogWarning($"[DeviceBindingSystem] {message}");
        }

        /// <summary>
        /// 错误日志
        /// </summary>
        private void LogError(string message)
        {
            if (enableDebugLogs)
                Debug.LogError($"[DeviceBindingSystem] {message}");
        }

        #endregion

        #region Data Structures

        /// <summary>
        /// 设备绑定数据结构
        /// </summary>
        [Serializable]
        private class DeviceBindingData
        {
            public List<DeviceInfo> devices;
            public DateTime lastUpdated;
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// 是否启用设备绑定
        /// </summary>
        public bool EnableDeviceBinding
        {
            get => enableDeviceBinding;
            set => enableDeviceBinding = value;
        }

        /// <summary>
        /// 当前设备信息
        /// </summary>
        public DeviceInfo CurrentDevice => currentDevice;

        /// <summary>
        /// 绑定设备数量
        /// </summary>
        public int BoundDeviceCount => boundDevices.Count;

        /// <summary>
        /// 是否正在验证
        /// </summary>
        public bool IsVerificationInProgress => isVerificationInProgress;

        #endregion
    }
}
